package cn.bluemobi.app.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import cn.bluemobi.app.core.mybatis.PageUtils;
import cn.bluemobi.app.entity.form.CommentForm;
import cn.bluemobi.app.entity.form.OrderForm;
import cn.bluemobi.app.entity.output.Address;
import cn.bluemobi.app.entity.output.Balance;
import cn.bluemobi.app.entity.output.BalanceCommodity;
import cn.bluemobi.app.entity.output.BalanceItem;
import cn.bluemobi.app.entity.output.Order;
import cn.bluemobi.app.entity.output.OrderItem;
import cn.bluemobi.app.entity.output.Pay;
import cn.bluemobi.app.mapper.AddressMapper;
import cn.bluemobi.app.mapper.OrderMapper;
import cn.bluemobi.app.service.OrderService;
import cn.bluemobi.app.utils.CommonUtils;
import cn.bluemobi.common.core.dto.Dto;
import cn.bluemobi.common.core.dto.Page;

/**
 * 
 * @author lvxh
 * 
 */
@Service
@Transactional
public class OrderServiceImpl implements OrderService {

	@Autowired
	private OrderMapper orderMapper;

	@Autowired
	private AddressMapper addressMapper;

	public double getMaxFreight(List<Double> list) {
		double max = Collections.max(list);
		return max;
	}

	private Map<String, List<BalanceCommodity>> balanceCommodityGroupList(
			List<BalanceCommodity> groupList) {
		Map<String, List<BalanceCommodity>> groupMap = new HashMap<String, List<BalanceCommodity>>();
		if (!CollectionUtils.isEmpty(groupList)) {
			for (BalanceCommodity BalanceCommodity : groupList) {
				if (groupMap.containsKey(BalanceCommodity.getMerchantId())) {
					List<BalanceCommodity> list = groupMap.get(BalanceCommodity
							.getMerchantId());
					list.add(BalanceCommodity);
				} else {
					List<BalanceCommodity> list = new ArrayList<BalanceCommodity>();
					list.add(BalanceCommodity);
					groupMap.put(BalanceCommodity.getMerchantId(), list);
				}
			}
		}
		return groupMap;
	}

	private Balance getBalanceInfo(String memberId,
			List<BalanceCommodity> balanceCommoditys) {
		Balance balance = new Balance();

		Double totalCommodityPrice = 0d;
		Double totalFreight = 0d;
		if (!CollectionUtils.isEmpty(balanceCommoditys)) {
			Map<String, List<BalanceCommodity>> balanceCommodityMap = balanceCommodityGroupList(balanceCommoditys);
			List<BalanceItem> balanceItems = new ArrayList<BalanceItem>();
			for (String key : balanceCommodityMap.keySet()) {
				BalanceItem balanceItem = orderMapper.findMerchantInfo(key);
				Double merchantCommodityPrice = 0d;
				Double merchantCommodityPoints = 0d;
				List<Double> freights = new ArrayList<Double>();
				List<BalanceCommodity> balanceCommodities = balanceCommodityMap
						.get(key);
				for (BalanceCommodity balanceCommodity : balanceCommodities) {
					merchantCommodityPrice += Integer.parseInt(balanceCommodity
							.getQuantity())
							* Double.parseDouble(balanceCommodity
									.getSpecificationPrice());
					merchantCommodityPoints += Integer
							.parseInt(balanceCommodity.getQuantity())
							* Double.parseDouble(balanceCommodity.getPoints());
					freights.add(Double.parseDouble(balanceCommodity
							.getFreight()));
				}
				Integer merchantCommodityCount = balanceCommodities.size();
				Double merchantFreight = getMaxFreight(freights);
				Double merchantTotalPrice = merchantFreight
						+ merchantCommodityPrice;
				balanceItem.setMerchantCommodityPoints(merchantCommodityPoints
						.toString());
				balanceItem.setMerchantCommodityCount(merchantCommodityCount
						.toString());
				balanceItem.setMerchantCommodityPrice(merchantCommodityPrice
						.toString());
				balanceItem
						.setMerchantTotalPrice(merchantTotalPrice.toString());
				balanceItem.setMerchantFreight(merchantFreight.toString());
				balanceItem.setBalanceCommoditys(balanceCommodities);
				balanceItems.add(balanceItem);

				totalFreight += merchantFreight;
				totalCommodityPrice += merchantCommodityPrice;
			}
			balance.setBalanceItems(balanceItems);
		}
		Integer totalCommodityCount = balanceCommoditys.size();
		Double totalPrice = totalFreight + totalCommodityPrice;
		balance.setTotalCommodityPrice(totalCommodityPrice.toString());
		balance.setTotalFreight(totalFreight.toString());
		balance.setTotalPrice(totalPrice.toString());
		balance.setTotalCommodityCount(totalCommodityCount.toString());
		// 默认地址
		Address address = addressMapper.findDefaultAddress(memberId);
		balance.setAddress(address);
		return balance;
	}

	@Override
	public Dto<Balance> balanceByCart(String memberId, String shoppingCartIds) {
		Dto<Balance> dto = new Dto<Balance>();
		List<String> shoppingCartIdList = Arrays.asList(shoppingCartIds
				.split(","));
		List<BalanceCommodity> balanceCommoditys = orderMapper
				.findCommodityByCartIds(shoppingCartIdList);
		Balance balance = getBalanceInfo(memberId, balanceCommoditys);
		dto.setData(balance);
		return dto;
	}

	@Override
	public Dto<Balance> balanceRightNow(String memberId, String commodityId,
			String specificationId, String quantity) {
		Dto<Balance> dto = new Dto<Balance>();
		List<BalanceCommodity> balanceCommoditys = orderMapper
				.findCommodityByCommodityId(commodityId, specificationId,
						quantity);
		Balance balance = getBalanceInfo(memberId, balanceCommoditys);
		dto.setData(balance);
		return dto;
	}

	@Override
	public Dto<Pay> submitOrder(String memberId, OrderForm orderForm) {
		Dto<Pay> dto = new Dto<Pay>();
		List<BalanceCommodity> balanceCommoditys = new ArrayList<BalanceCommodity>();
		if (StringUtils.equals(orderForm.getSettlementType(), "0")) {
			balanceCommoditys = orderMapper.findCommodityByCommodityId(
					orderForm.getCommodityId(), orderForm.getSpecificationId(),
					orderForm.getQuantity());
		}
		if (StringUtils.equals(orderForm.getSettlementType(), "1")) {
			List<String> shoppingCartIdList = Arrays.asList(orderForm
					.getShoppingCartIds().split(","));
			balanceCommoditys = orderMapper
					.findCommodityByCartIds(shoppingCartIdList);
		}
		if (CollectionUtils.isEmpty(balanceCommoditys)) {
			dto.errorMsg("请选择要购买的商品");
			return dto;
		}
		if (StringUtils.isEmpty(orderForm.getAddressId())) {
			dto.errorMsg("请选择收货地址");
			return dto;
		}
		boolean flag = true;
		StringBuffer buffer = new StringBuffer();
		for (BalanceCommodity balanceCommodity : balanceCommoditys) {
			if (orderMapper.checkCommoditySupplyCount(orderForm) > 0) {
				flag = false;
				buffer.append(balanceCommodity.getCommodityName() + ","
						+ balanceCommodity.getSpecificationName() + "库存不足");
				break;
			}
		}
		if (flag == false) {
			dto.errorMsg(buffer.toString());
			return dto;
		}
		if (StringUtils.equals(orderForm.getIsPointsExchange(), "1")
				&& orderMapper.checkmMemberConsumePoints(
						orderForm.getCanExchangePoints(), memberId) <= 0) {
			dto.errorMsg("积分不足");
			return dto;
		}
		Balance balance = getBalanceInfo(memberId, balanceCommoditys);
		List<BalanceItem> balanceItems = balance.getBalanceItems();
		String orderNumbers = "";
		Double totalPayMoney = 0d;
		List<String> orderNos = new ArrayList<String>();
		for (BalanceItem balanceItem : balanceItems) {
			// 生成订单
			Map<String, Object> orderParams = new HashMap<String, Object>();
			// 订单号YYYYMMddHHmm时间+6位随机数
			String orderNumber = CommonUtils.currentDate("YYYYMMddHHmm")
					+ CommonUtils.createNumber(6);
			orderParams.put("memberId", memberId);
			orderParams.put("orderNumber", orderNumber);
			orderParams.put("merchantId", balanceItem.getMerchantId());
			orderParams.put("addressId", orderForm.getAddressId());
			orderParams.put("orderStatus", "0");
			orderParams.put("commodityMoney",
					balanceItem.getMerchantCommodityPrice());
			orderParams.put("freight", balanceItem.getMerchantFreight());
			orderParams.put("payMoney", balanceItem.getMerchantTotalPrice());
			if (StringUtils.equals(orderForm.getIsPointsExchange(), "1")) {
				orderParams.put("commodityMoney",
						balanceItem.getMerchantCommodityPoints());
				orderParams.put("freight", "0");
				orderParams.put("payMoney",
						balanceItem.getMerchantCommodityPoints());
			}
			orderMapper.insertOrder(orderParams);
			// 生成订单详情
			Map<String, Object> orderItemParams = new HashMap<String, Object>();
			orderItemParams.put("orderId", orderParams.get("id"));
			orderItemParams.put("balanceCommodityList",
					balanceItem.getBalanceCommoditys());
			orderMapper.insertOrderInfo(orderItemParams);
			// 修改商品库存
			orderMapper.updateCommoditySupplyCount(balanceItem
					.getBalanceCommoditys());

			orderNos.add(orderNumber);
			orderNumbers = StringUtils.join(orderNos.toArray(), ",");
			totalPayMoney += Double.parseDouble(balanceItem
					.getMerchantTotalPrice());

		}
		// 修改默认地址
		addressMapper.updateDefaultAddress("1", orderForm.getAddressId());
		addressMapper.updateAddressNotDefault(memberId,
				orderForm.getAddressId());
		// 删除购物车
		if (StringUtils.equals(orderForm.getSettlementType(), "1")) {
			List<String> shoppingCartIdList = Arrays.asList(orderForm
					.getShoppingCartIds().split(","));
			orderMapper.deleteShoppingCart(shoppingCartIdList);
		}
		if (StringUtils.equals(orderForm.getIsPointsExchange(), "0")) {
			Pay pay = new Pay();
			pay.setOrderNumber(orderNumbers);
			pay.setPayMoney(totalPayMoney.toString());
			dto.setData(pay);
		}
		if (StringUtils.equals(orderForm.getIsPointsExchange(), "1")) {
			updatePointsForPaySusscess(memberId, orderNumbers, "0",
					orderForm.getCanExchangePoints(), balanceCommoditys);
			dto.setMsg("兑换成功");
			dto.setData(null);
		}
		return dto;
	}

	private void updatePointsForPaySusscess(String memberId,
			String orderNumbers, String payType, String payMoney,
			List<BalanceCommodity> balanceCommodities) {
		// 修改商品订单信息
		List<String> orderNumberList = Arrays.asList(orderNumbers.split(","));
		Map<String, Object> orderParams = new HashMap<>();
		orderParams.put("orderNumberList", orderNumberList);
		orderParams.put("payType", payType);
		orderParams.put("payMoney", payMoney);
		orderParams.put("orderStatus", "1");
		System.out.println("==========================修改订单信息："
				+ orderParams.toString());
		orderMapper.updateOrder(orderParams);
		// 修改商品销量
		orderMapper.updateCommodityBuyCount(balanceCommodities);
		// 修改用户消费积分
		orderMapper.updateMemberConsumePoints(payMoney, memberId);

		// 新增积分明细
		orderMapper.insertPointsDetail(memberId, payMoney, "1", "积分兑换商品");
	}

	@Override
	public Page<Order> findMyOrders(Integer pageNo, Integer pageSize,
			String memberId, String orderStatus) {
		Page<Order> page = PageUtils.startPage(pageNo, pageSize);
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("memberId", memberId);
		params.put("orderStatus", orderStatus);
		List<Order> orders = orderMapper.findOrders(params);
		if (!CollectionUtils.isEmpty(orders)) {
			for (Order order : orders) {
				List<OrderItem> items = orderMapper.findOrderItem(order
						.getOrderId());
				order.setOrderItems(items);
				Address address = addressMapper.findAddressDetail(order
						.getAddressId());
				order.setAddress(address);
			}
		}
		page.setList(orders);
		return page;
	}

	@Override
	public Dto<Order> findOrderDetail(String memberId, String orderId) {
		Dto<Order> dto = new Dto<Order>();
		Order order = orderMapper.findOrderByOrderId(orderId);
		if (order != null) {
			List<OrderItem> items = orderMapper.findOrderItem(order
					.getOrderId());
			order.setOrderItems(items);
			Address address = addressMapper.findAddressDetail(order
					.getAddressId());
			order.setAddress(address);
		}
		dto.setData(order);
		return dto;
	}

	@Override
	public Dto<Object> cancelOrder(String memberId, String orderId) {
		Dto<Object> dto = new Dto<Object>();
		orderMapper.cancelOrder(memberId, orderId);
		Order order = orderMapper.findOrderByOrderId(orderId);
		if (order != null && StringUtils.equals(order.getPayMoney(), "0")) {
			orderMapper.updateAddMemberPoints(order.getPayMoney(), memberId);
		}
		return dto;
	}

	@Override
	public Dto<Object> deleteOrder(String memberId, String orderId) {
		Dto<Object> dto = new Dto<Object>();
		orderMapper.deleteOrder(memberId, orderId);
		return dto;
	}

	@Override
	public Dto<Object> confirmReceipt(String memberId, String orderId) {
		Dto<Object> dto = new Dto<Object>();
		orderMapper.confirmReceipt(memberId, orderId);
		return dto;
	}

	//
	// @Override
	// public Dto<Object> applyAfterSales(String memberId,
	// OrderReturnForm orderReturnForm) {
	// Dto<Object> dto = new Dto<Object>();
	// String returnRefundNumber = CommonUtils.currentDate("yyyyMMddHHmm")
	// + CommonUtils.createNumber(6);
	// orderReturnForm.setReturnRefundNumber(returnRefundNumber);
	// orderReturnForm.setMemberId(memberId);
	// // 新增售后
	// orderMapper.insertOrderReturn(orderReturnForm);
	// // 新增售后详情
	// orderReturnForm.setReturnRefundId(orderReturnForm.getId());
	// orderMapper.insertOrderReturnInfo(orderReturnForm);
	// // 新增售后图片
	// if (!StringUtils.isEmpty(orderReturnForm.getImageUrls())) {
	// List<String> imageUrls = Arrays.asList(orderReturnForm
	// .getImageUrls().split(","));
	// Map<String, Object> imageUrlParams = new HashMap<String, Object>();
	// imageUrlParams.put("returnRefundId", orderReturnForm.getId());
	// imageUrlParams.put("imageUrlList", imageUrls);
	// orderMapper.insertOrderReturnImage(imageUrlParams);
	// }
	// // 修改订单详情售后状态
	// orderMapper.updateOrderInfoAfterSalesStatus("1",
	// orderReturnForm.getOrderInfoId());
	// return dto;
	// }
	//
	// @Override
	// public Dto<Logistics> findLogisticsDetail(String memberId, Long orderId,
	// String logisticsCode, String logisticsCompany,
	// String logisticsNumber) {
	// Dto<Logistics> dto = new Dto<Logistics>();
	// Logistics logistics = getLogistics(logisticsCode, logisticsCompany,
	// logisticsNumber);
	// dto.setData(logistics);
	// return dto;
	// }
	//
	// @SuppressWarnings("unchecked")
	// private Logistics getLogistics(String logisticsCode,
	// String logisticsCompany, String logisticsNumber) {
	// Logistics logistics = new Logistics();
	// if (!StringUtils.isEmpty(logisticsCode)
	// && !StringUtils.isEmpty(logisticsNumber)) {
	// Map<String, Object> resultMap = LogisticsUtils.findLogisticsDetail(
	// logisticsCode, logisticsNumber);
	// if (!CollectionUtils.isEmpty(resultMap)) {
	// if (StringUtils.equals(resultMap.get("result").toString(), "0")) {
	// Map<String, Object> logisticsMap = (Map<String, Object>) resultMap
	// .get("logisticsMap");
	// logistics.setLogisticsCode(logisticsMap.get("com")
	// .toString());
	// logistics.setLogisticsCompany(logisticsMap.get("company")
	// .toString());
	// logistics.setLogisticsNumber(logisticsMap.get("no")
	// .toString());
	// logistics.setReason(resultMap.get("reason").toString());
	// logistics
	// .setLogisticsDetails((List<LogisticsDetail>) logisticsMap
	// .get("logisticsInfoList"));
	// } else {
	// logistics.setLogisticsCode(logisticsCode);
	// logistics.setLogisticsCompany(logisticsCompany);
	// logistics.setLogisticsNumber(logisticsNumber);
	// logistics.setReason(resultMap.get("reason").toString());
	// }
	// }
	// }
	// return logistics;
	// }
	//
	@Override
	public Dto<Object> commentProduct(String memberId, CommentForm commentForm) {
		Dto<Object> dto = new Dto<Object>();
		commentForm.setMemberId(memberId);
		orderMapper.insertComment(commentForm);

		// 新增商品评价图片
		if (!StringUtils.isEmpty(commentForm.getImageUrls())) {
			List<String> imageUrls = Arrays.asList(commentForm.getImageUrls()
					.split(","));
			Map<String, Object> imageUrlParams = new HashMap<String, Object>();
			imageUrlParams.put("evaluateId", commentForm.getId());
			imageUrlParams.put("imageUrlList", imageUrls);
			orderMapper.insertCommentImage(imageUrlParams);
		}
		// 修改订单详情商品评价状态
		orderMapper.updateOrderInfoCommentStatus("1",
				commentForm.getOrderInfoId());
		// 验证是否订单商品是否评价完成
		if (orderMapper.checkIsCommentFinish("0", commentForm.getOrderId()) <= 0) {
			orderMapper.updateOrderFinish(commentForm.getMemberId(),
					commentForm.getOrderId());
		}

		return dto;
	}

}
